using System;
using System.Collections.Generic;
using System.Text;

using Deepcode.Flux.Core.Systems.Workflow;
using Deepcode.Flux.Core.Systems.Workflow.Attribs;
using Deepcode.Flux.Core.Systems.Workflow.BaseHandlers;
using Deepcode.Flux.Core.Systems.Workflow.Bases;
using Deepcode.Flux.Core.Systems.Workflow.Enums;
using Deepcode.Flux.Core.Systems.Workflow.Info;
using Deepcode.Flux.Core.Systems.Security;
using Deepcode.Flux.Core.Systems.CMS;
using Deepcode.Flux.Core.Systems.CMS.TemplateGallery;

namespace Deepcode.Flux.Core.Systems.CMS.Workflow
{
	/// <summary>
	/// This is the workflow handler for content
	/// </summary>
	public class CMS : Deepcode.Flux.Core.Systems.Workflow.BaseHandlers.FluxBaseHandler
	{
		#region Data Cache
		/// <summary>
		/// Cache of the content object
		/// </summary>
		private ContentObject _Item = null;
		/// <summary>
		/// Obtain a copy of the content object
		/// </summary>
		/// <param name="DataID"></param>
		/// <returns></returns>
		private ContentObject GetRecord(int DataID)
		{
			if((( _Item != null ) && (_Item.PK_ID != DataID)) || (_Item == null))
			{
				ContentManager cms = new ContentManager(true);
				_Item = cms.AdxGetByID( DataID );
			}
			return _Item;
		}
		#endregion
		#region Data Dictionary
		/// <summary>
		/// Exposes the data dictionary information to a workflow method
		/// </summary>
		/// <returns></returns>
		public override WorkflowDataDictionaryDescriptor GetDataDictionary()
		{
			WorkflowDataDictionaryDescriptor Dic = new WorkflowDataDictionaryDescriptor();
			Dic.Add("ID", "The ID of the content object");
			Dic.Add("NodeTitle", "The administration title of the node");
			Dic.Add("OwnerName", "The Name of the user that last checked in");
			Dic.Add("OwnerEmail", "The Email of the user that last checked in");
			return Dic;
		}
		/// <summary>
		/// Retrieve value from a data dictionary
		/// </summary>
		/// <param name="Key"></param>
		/// <param name="DataID"></param>
		/// <returns></returns>
		public override string DataDictionaryItem(string Key, int DataID)
		{
			ContentObject o = this.GetRecord( DataID );
			if( o == null ) return "";

			switch (Key)
			{
				case "ID":
					return o.PK_ID.ToString();
				case "NodeTitle":
					return o.NodeTitle;
				case "OwnerName":
					Deepcode.Flux.Core.Systems.Security.AdministrationUser user = o.CheckedInBy;
					if( user == null ) return "No user";
					return user.RealName;
				case "OwnerEmail":
					Deepcode.Flux.Core.Systems.Security.AdministrationUser user2 = o.CheckedInBy;
					if (user2 == null) return "";
					return user2.EMailAddress;
			}
			return "";
		}
		#endregion
		#region Delete checking functionality
		/// <summary>
		/// Override the CanBeDeleted function. Do normal checks
		/// and then ensure no entries have the definition
		/// associated with it.
		/// </summary>
		/// <param name="DefinitionID"></param>
		/// <returns></returns>
		public override bool CanBeDeleted(int DefinitionID)
		{
			return base.CanBeDeleted( DefinitionID );
		}
		#endregion
		#region View and Edit URL
		/// <summary>
		/// Implement functionality to obtain a VIEW url for the data object
		/// </summary>
		/// <param name="Task"></param>
		/// <returns></returns>
		public override string GetViewURL(Task task)
		{
			ContentManager cms = new ContentManager(true);
			ContentObject o = cms.AdxGetByID( task.FK_DataID );
			if (o != null && o.TypeTemplate != null)
			{
				if (o.TypeTemplate.WFViewForm != "")
				{
					return String.Format("{0}{1}&ID={2}&TaskID={3}",
						o.TypeTemplate.WFViewForm,
						o.TypeTemplate.WFViewForm.Contains("?") ? "" : "?",
						task.FK_DataID,
						task.PK_ID);
				}
			}
			return String.Format("~/admin/private/cms/workflow/ui_View.aspx?ID={0}&TaskID={1}", task.FK_DataID, task.PK_ID );
		}
		/// <summary>
		/// Implement functionality to obtain an EDIT url for the data object
		/// </summary>
		/// <param name="Task"></param>
		/// <returns></returns>
		public override string GetEditURL(Task task)
		{
			ContentManager cms = new ContentManager(true);
			ContentObject o = cms.AdxGetByID(task.FK_DataID);
			if (o != null && o.TypeTemplate != null)
			{
				if (o.TypeTemplate.WFEditForm != "")
				{
					return String.Format("{0}{1}&ID={2}&TaskID={3}",
						o.TypeTemplate.WFEditForm,
						o.TypeTemplate.WFEditForm.Contains("?") ? "" : "?",
						task.FK_DataID,
						task.PK_ID);
				}
			}
			return "";
		}
		#endregion
		#region Workflow Methods
		/// <summary>
		/// Publish the content to live
		/// </summary>
		/// <param name="engine"></param>
		/// <param name="ProcessID"></param>
		/// <param name="DataID"></param>
		/// <param name="DataName"></param>
		/// <param name="PropertyBag"></param>
		[WorkflowMethod("Set the content object to published")]
		public void PublishContent(WorkflowEngine engine, int ProcessID, int DataID, string DataName, string PropertyBag)
		{
			ContentManager cms = new ContentManager();
			ContentObject obj = cms.AdxGetByID( DataID );

			if( obj != null )
				cms.PublishVersion( DataID, obj.FK_CheckedInBy );
		}
		/// <summary>
		/// Reject the content back to author
		/// </summary>
		/// <param name="engine"></param>
		/// <param name="ProcessID"></param>
		/// <param name="DataID"></param>
		/// <param name="DataName"></param>
		/// <param name="PropertyBag"></param>
		[WorkflowMethod("Reject content back to check-in user")]
		public void RejectContent(WorkflowEngine engine, int ProcessID, int DataID, string DataName, string PropertyBag)
		{
			ContentManager cms = new ContentManager();
			ContentObject obj = cms.AdxGetByID( DataID );

			if (obj != null)
			{
				if( obj.CheckedInBy != null )
					cms.CheckOut( DataID, obj.FK_CheckedInBy );
			}
		}
		#endregion
		#region Special user callbacks
		/// <summary>
		/// This special taskable method returns the user that checked the content in last
		/// </summary>
		[WorkflowTaskableMethod("Last Checked-In user")]
		public int[] LastCheckin(WorkflowEngine Engine, UserCallbackType Type, int ProcessID, int DataID, string DataName)
		{
			if (Type == UserCallbackType.REQUEST_USERS)
			{
				List<int> items = new List<int>();

				ContentManager cms = new ContentManager();
				ContentObject obj = cms.AdxGetByID( DataID );
				if( obj != null )
					if( obj.CheckedInBy != null )
						items.Add( obj.FK_CheckedInBy );
				
				return items.ToArray();
			}
			if (Type == UserCallbackType.REQUEST_GROUPS)
			{
				List< int > items = new List<int>();
				return items.ToArray();
			}
			return null;
		}		
		#endregion
	}
}
